<template>
  <div class="home" v-loading="loading">
    <el-button type="primary" icon="el-icon-menu" class="merge" @click="handleMerge" v-if="checkList.length > 0">合并</el-button>
    <div class="layout">

      <div class="screenfull" @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp">
        <div class="mask" v-show="isSelecting" :style="
            'width:' +
            mask_width + 'px;' +
            'height:' +
            mask_height + 'px;' +
            'left:' +
            mask_left + 'px;' +
            'top:' +
            mask_top + 'px;'
          "
        ></div>
      </div>
      <el-table
        :data="tableData"
        :span-method="arraySpanMethod"
        >
        <el-table-column label="" v-for="(item,index) in 12" :key="index">
          <template slot-scope="scope">
            <el-button icon="el-icon-plus" class="size1" :index="scope.row[index]" :class="{'checked': checkList.includes(scope.row[index]), 'grey': saveIndexs.includes(scope.row[index])}" @click="cellClick(scope.row[index])">
            {{scope.row[index]}}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="footer">
      <el-button type="primary" @click="saveLayout">保存</el-button>
      <el-button type="warning" @click="handleClear">重置</el-button>
      <el-button @click="goBack()">返回</el-button>
    </div>
  </div>
</template>

<script>
  import { queryPage, updateByModel } from "@/api/systemBuilding/layout"

  export default {
    data() {
      return {
        systemCode: "",
        menuCode: "",
        loading: false,
        tableData: [],  //表格，二维数组

        checkList: [],  //合并时选中的格子index
        layoutTableSet: [],  //合并的集合
        saveIndexs: [],

        isSelecting: false, // 是否正在框选
        startSelection: null, // 开始框选的位置
        endSelection: null, // 结束框选的位置

        fullLeft: 0, // 选择区域离左边距
        fullTop: 0, // 选择区域离上边距
        mask_width: 0,
        mask_left: 0,
        mask_height: 0,
        mask_top: 0,
      }
    },
    created() {
      this.systemCode = this.$route.query.systemCode;
      this.menuCode = this.$route.query.menuCode;
      this.getAccountData()
    },
    methods: {
      handleMouseDown(event) {
        let screenfullObj =document.getElementsByClassName("screenfull")[0].getBoundingClientRect();
        this.fullLeft = screenfullObj.left;
        this.fullTop = screenfullObj.top;
        this.isSelecting = true;
        this.startSelection = { x: event.clientX, y: event.clientY };
        this.mask_top = event.clientY - this.fullTop;
        this.mask_left = event.clientX - this.fullLeft;
      },

      handleMouseMove(event) {
        if (this.isSelecting) {
          this.endSelection = { x: event.clientX, y: event.clientY };
          this.mask_width = event.clientX - this.mask_left - this.fullLeft;
          this.mask_height = event.clientY - this.mask_top - this.fullTop;
        }
      },

      handleMouseUp() {
        this.isSelecting = false;
        if (this.endSelection) {
          // 逻辑处理
          const buttons = document.getElementsByClassName("size1");
          buttons.forEach(button => {
            let rect = button.getBoundingClientRect();
            if(((rect.x >= this.startSelection.x && rect.x <= this.endSelection.x) || (rect.x + rect.width >= this.startSelection.x && rect.x + rect.width <= this.endSelection.x)) &&
            ((rect.y >= this.startSelection.y && rect.y <= this.endSelection.y) || (rect.y + rect.height >= this.startSelection.y && rect.y + rect.height <= this.endSelection.y))) {
              this.cellClick(parseInt(button.getAttribute("index")));
            } else if(rect.x <= this.startSelection.x && rect.x + rect.width >= this.endSelection.x &&
            ((rect.y <= this.startSelection.y && rect.y + rect.height >= this.startSelection.y) || (rect.y >= this.startSelection.y && rect.y <= this.endSelection.y ))) {
              this.cellClick(parseInt(button.getAttribute("index")));
            } else if(rect.y <= this.startSelection.y && rect.y + rect.height >= this.endSelection.y &&
            ((rect.x <= this.startSelection.x && rect.x + rect.width >= this.startSelection.x) || (rect.x >= this.startSelection.x && rect.x <= this.endSelection.x ))) {
              this.cellClick(parseInt(button.getAttribute("index")));
            }
          })
        }
        this.startSelection = null;
        this.endSelection = null;
        this.mask_width = 0;
        this.mask_height = 0;
      },

      /**
       * 获取布局方法
       */
      async getAccountData() {
        this.loading = true
        this.tableData = [];
        this.layoutTableSet = [];
        this.saveIndexs = [];

        const {object} = await queryPage({
          systemCode: this.systemCode,
          menuCode: this.menuCode
        })
        let list = object || [];
        list.forEach(item => {
          this.layoutTableSet.push({
            index: item.indexNum,
            col: item.sizeType.split("*")[1],
            row: item.sizeType.split("*")[0]
          })
          this.saveIndexs.push(item.indexNum)
        })

        for(let i = 1; i <= 6; i++) {
          let arr = []
          for(let j = 1; j <= 12; j++) {
            arr.push(j + (i - 1) * 12);
          }
          this.tableData.push(arr);
        }
        this.loading = false
        this.$nextTick(() => {
          this.tableRowClassName();
        })
      },

      /**
       * 合并表格方法
       */
      arraySpanMethod({ row, column, rowIndex, columnIndex }) {
        let index = columnIndex + 1 + rowIndex * 12;
        for(let i in this.layoutTableSet) {
          if(this.layoutTableSet[i].index == index) {
            return [this.layoutTableSet[i].col || 1, this.layoutTableSet[i].row || 1];
          } else if(this.layoutTableSet[i].row && this.layoutTableSet[i].col) {
            let arr = [];
            for(let k = 0; k < this.layoutTableSet[i].col; k++) {
              for(let m = 0; m < this.layoutTableSet[i].row; m++) {
                if(k == 0 && m == 0) {
                  continue;
                }
                arr.push(this.layoutTableSet[i].index + m + k * 12);
              }
            }
            if(arr.includes(index)) {
              return [0, 0]
            }
          } else if(this.layoutTableSet[i].row && (index > this.layoutTableSet[i].index && index < this.layoutTableSet[i].index + this.layoutTableSet[i].row)) {
            return [0, 0]
          } else if(this.layoutTableSet[i].col && (index > this.layoutTableSet[i].index && (index - this.layoutTableSet[i].index) % 12 == 0 && (index - this.layoutTableSet[i].index) / 12 < this.layoutTableSet[i].col)) {
            return [0, 0]
          }
        }
      },

      // 行样式调整
      tableRowClassName() {
        let rows = document.getElementsByClassName("el-table__row");
        let arr = [];
        let obj = rows[0];
        let num = 1;
        let height = document.getElementsByTagName("tbody")[0].getBoundingClientRect().height / 6;
        for(let i = 0; i < rows.length; i++) {
          if(rows[i].childNodes.length == 0) {
            num ++;
            rows[i].className = "el-table__row row0";
            obj.style.height = height * num + "px";
          } else {
            obj = rows[i];
            num = 1;
          }
          arr.push(rows[i].childNodes.length);
        }
        return '';
      },

      goBack() {
        this.$router.go(-1)
      },

      /**
       * 每个块的点击事件
       */
      cellClick(index) {
        let v = this.checkList.indexOf(index)
        if(v > -1) {
          this.checkList.splice(v, 1)
        } else {
          this.checkList.push(index)
        }
      },

      /**
       * 计算合并对象
       */
      handleMerge() {
        let arr = [];
        let dIndex = [];
        this.layoutTableSet.forEach((item, index) => {
          // 包含合并过的格子
          if(this.checkList.includes(item.index)) {
            for(let k = 0; k < (item.col || 1); k++) {
              for(let m = 0; m < (item.row || 1); m++) {
                if(k == 0 && m == 0) {
                  continue;
                }
                arr.push(item.index + m + k * 12);
              }
            }

            dIndex.push(item.index)
          }
        })

        this.checkList = this.checkList.concat(arr);

        this.checkList.sort((a, b) => {
          return a-b
        })

        if(this.isContinuityNum(this.checkList, 1)) { //横向合并
          this.freshLayoutList(dIndex, 0, this.checkList.length)

        } else if(this.isContinuityNum(this.checkList, 12)) { //纵向合并
          this.freshLayoutList(dIndex, this.checkList.length, 0)
        } else {  //田字型合并
          let isFail = true;
          let col = this.getColNum(this.checkList);

          if(col == 1 && !this.isContinuityNum(this.checkList, 12)) {
            this.resetLayoutSet(arr);
            return this.$message.warning("无法合并，请重试！")
          }
          if((this.checkList[this.checkList.length - 1] - this.checkList[col - 1]) % 12 != 0) {
            this.resetLayoutSet(arr);
            return this.$message.warning("无法合并，请重试！")
          }

          if(this.checkList.length % col == 0) {
            let forIndex = 0;
            for(let j = 0; j < this.checkList.length / col; j++) {
              if(this.isContinuityNum(this.checkList.slice(j*col, j*col + col), 1)){
                forIndex++;
              } else {
                break;
              }
            }

            if(forIndex == this.checkList.length / col) {
              this.freshLayoutList(dIndex, forIndex, col)
              isFail = false;
            }
          }

          if(isFail) {
            this.resetLayoutSet(arr);
            this.$message.warning("无法合并，请重试！")
          }
        }

        this.$nextTick(() => {
          this.tableRowClassName();
        })
      },

      /**
       * 刷新集合
       */
      freshLayoutList(dIndex, col, row) {
        this.layoutTableSet = this.layoutTableSet.filter(item => {
          return !dIndex.includes(item.index);
        })
        let data = {
          index: this.checkList[0]
        }
        if(col) {
          data.col = col;
        }
        if(row) {
          data.row = row;
        }
        this.layoutTableSet.push(data)
        this.saveIndexs = this.layoutTableSet.map(item => {
          return item.index
        })
        this.checkList = [];
      },

      resetLayoutSet(arr) {
        if(arr && arr.length > 0) {
          this.checkList = this.checkList.filter(item => {
            return !arr.includes(item);
          })
        }
      },

      /**
       * 判断行内占几格
       */
      getColNum(arr) {
        let val = arr[0];
        let isContinuation = true;
        for (let i in arr) {
          if (arr[i] != val) {
            isContinuation = false;
            break;
          }
          val ++;
        }
        return val - arr[0];
      },

      /**
       * 判断是否连续格子
       */
      isContinuityNum(arr, num) {
        let val = arr[0];
        let isContinuation = true;
        for (let i in arr) {
          if (arr[i] != val) {
            isContinuation = false;
            break;
          }
          val += num;
        }
        return isContinuation;
      },

      /**
       * 重置布局
       */
      handleClear() {
        location.reload();
      },

      /**
       * 保存布局
       */
      async saveLayout() {
        this.loading = true
        let mapString1 = [];
        this.layoutTableSet.forEach(item => {
          mapString1.push({
            systemCode: this.systemCode,
            menuCode: this.menuCode,
            indexNum: item.index,
            sizeType: (item.row || 1) + "*" + (item.col || 1)
          })
        })

        const {message, status} = await updateByModel({
          menuCode: this.menuCode,
          mapString1: JSON.stringify(mapString1)
        });
        if (status == 200) {
          this.getAccountData()
          this.$message.success(message)
        }
        this.loading = false
      },
    }
  }
</script>

<style lang="scss" scoped>
  .home {
    width: 100%;
    height: calc(100vh - 50px);
    display: flex;
    flex-direction: column;
  }

  .mask {
    position: absolute;
    background: rgba(0, 255, 0, 0.2);
    border: 1px solid red;
    z-index: 20;
  }
  .screenfull {
    position: absolute;
    width: 100%;
    height: calc(100% - 170px);
    z-index: 10;
  }

  .merge {
    position: absolute;
    z-index: 20;
  }

  .layout {
    flex: 1;

    .el-table {
      width: 100%;
      height: 100%;
      border: none;

      &::before {
        background-color: transparent;
      }

      ::v-deep.el-table__header-wrapper {
        display: none;
      }

      ::v-deep.el-table__body-wrapper, ::v-deep.el-table__body {
        width: 100%;
        height: 100%;

        tr {
          height: calc(100% / 6);

          &.row0 {
            height: 0;
          }

          &.el-table__row:hover {
            td {
              background-color: transparent;
            }
          }
        }

        td.el-table__cell {
          padding: 0;
          border: none;
        }

        .cell {
          height: 100%;
          padding: 8px;
        }
      }
    }

    .size1 {
      width: 100%;
      height: 100%;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
      border: none;
      border-radius: 10px;

      &:focus {
        background-color: #FFF;
        color: #606266;
      }

      ::v-deep.el-icon-plus:before {
        font-size: 30px;
      }

      &.checked, &:hover {
        color: #409EFF;
        background-color: #ecf5ff !important;
      }

      &.grey {
        background-color: #D9D9D9;
      }
    }
  }

  .footer {
    height: 90px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
</style>
